package com.baitiaojun.video.api.impl;

import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.baitiaojun.api.annotation.UserAuthoritiesAccess;
import com.baitiaojun.api.domain.video.Video;
import com.baitiaojun.api.domain.video.VideoView;
import com.baitiaojun.api.exception.ConditionException;
import com.baitiaojun.api.util.ConstantUtil;
import com.baitiaojun.api.vo.JsonRes;
import com.baitiaojun.api.vo.LikeCoinOperatedCollectedInfo;
import com.baitiaojun.api.vo.PageInfo;
import com.baitiaojun.video.api.VideoApi;
import com.baitiaojun.video.config.properties.VideoAreaProperties;
import com.baitiaojun.video.feign.ElasticsearchVideoFeign;
import com.baitiaojun.video.handler.GlobalSystemDefendHandler;
import com.baitiaojun.video.service.*;
import com.baitiaojun.video.support.UserSupport;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * @类名 VideoApiImpl
 * @描述 TODO
 * @作者 白条君
 * @创建日期 2022/12/19 14:33
 * @版本 1.0
 */
@RestController
public class VideoApiImpl implements VideoApi {

    @Autowired
    private VideoService videoService;

    @Resource
    private UserSupport userSupport;

    @Autowired
    private HttpServletRequest request;

    @Resource
    private VideoAreaProperties videoAreaProperties;

    @Autowired
    private ElasticsearchVideoFeign elasticsearchVideoFeign;

    @Autowired
    private VideoCollectionService videoCollectionService;

    @Autowired
    private VideoCoinService videoCoinService;

    @Autowired
    private VideoRecommendService videoRecommendService;

    @Autowired
    private VideoLikeService videoLikeService;

    @Autowired
    private VideoViewService videoViewService;

    @UserAuthoritiesAccess(
            accessRole = {ConstantUtil.ROLE_LV0
                    ,ConstantUtil.ROLE_LV1
                    ,ConstantUtil.ROLE_LV2
                    ,ConstantUtil.ROLE_LV3
                    ,ConstantUtil.ROLE_LV4
                    ,ConstantUtil.ROLE_LV5
                    ,ConstantUtil.ROLE_LV6
            })
    @Override
    public JsonRes addVideo(Video video) throws Exception {
        Long userId = userSupport.getCurrentUserId(request);
        video.setUserId(userId);
        Long videoId = videoService.addVideo(video);
        videoService.asyncPublishMoments(videoId, video);
        return JsonRes.builder().success().data(videoId);
    }

    @Override
    public JsonRes getVideoArea() {
        List<String> names = videoAreaProperties.getNames();
        return JsonRes.builder().data(names);
    }

    @Override
    public PageInfo getPageAreaListVideos(Long lastId, Integer pageSize, String area) throws IOException {
        if (ObjectUtils.isEmpty(lastId)) {
            lastId = 0L;
        }
        List<Video> videos = elasticsearchVideoFeign.getPageHomeVideoList(lastId, pageSize, area);
        return PageInfo.builder().pageList(videos).size(videos.size()).build();
    }

    @UserAuthoritiesAccess(
            accessRole = {ConstantUtil.ROLE_LV0
                    ,ConstantUtil.ROLE_LV1
                    ,ConstantUtil.ROLE_LV2
                    ,ConstantUtil.ROLE_LV3
                    ,ConstantUtil.ROLE_LV4
                    ,ConstantUtil.ROLE_LV5
                    ,ConstantUtil.ROLE_LV6
            })
    @Override
    public JsonRes addVideoLike(Long videoId) throws Exception {
        Long userId = userSupport.getCurrentUserId(request);
        videoLikeService.addVideoLike(videoId, userId);
        return JsonRes.builder().success();
    }

    @UserAuthoritiesAccess(
            accessRole = {ConstantUtil.ROLE_LV0
                    ,ConstantUtil.ROLE_LV1
                    ,ConstantUtil.ROLE_LV2
                    ,ConstantUtil.ROLE_LV3
                    ,ConstantUtil.ROLE_LV4
                    ,ConstantUtil.ROLE_LV5
                    ,ConstantUtil.ROLE_LV6
            })
    @Override
    public JsonRes cancelVideoLike(Long videoId) throws Exception {
        Long userId = userSupport.getCurrentUserId(request);
        videoLikeService.cancelVideoLike(videoId, userId);
        return JsonRes.builder().success();
    }

    @Override
    public JsonRes getVideoLike(Long videoId) {
        //用户没有进行登录也可以查看到点赞数量，所以先获取用户id，如果无法获取就异常捕获，不进行处理
        Long userId = null;
        try {
            userId = userSupport.getCurrentUserId(request);
        } catch (Exception e) {}
        LikeCoinOperatedCollectedInfo likeCoinOperatedSubInfo = videoLikeService.getVideoLike(userId, videoId);
        return JsonRes.builder().success().data(likeCoinOperatedSubInfo);
    }

    @UserAuthoritiesAccess(
            accessRole = {ConstantUtil.ROLE_LV0
                    ,ConstantUtil.ROLE_LV1
                    ,ConstantUtil.ROLE_LV2
                    ,ConstantUtil.ROLE_LV3
                    ,ConstantUtil.ROLE_LV4
                    ,ConstantUtil.ROLE_LV5
                    ,ConstantUtil.ROLE_LV6
            })
    @Override
    public JsonRes addVideoCollection(Long videoId, Long groupId) throws Exception {
        Long userId = userSupport.getCurrentUserId(request);
        videoCollectionService.addVideoCollection(videoId, userId, groupId);
        return JsonRes.builder().success();
    }

    @UserAuthoritiesAccess(
            accessRole = {ConstantUtil.ROLE_LV0
                    ,ConstantUtil.ROLE_LV1
                    ,ConstantUtil.ROLE_LV2
                    ,ConstantUtil.ROLE_LV3
                    ,ConstantUtil.ROLE_LV4
                    ,ConstantUtil.ROLE_LV5
                    ,ConstantUtil.ROLE_LV6
            })
    @Override
    public JsonRes cancelVideoCollection(Long videoId) throws Exception {
        Long userId = userSupport.getCurrentUserId(request);
        videoCollectionService.cancelVideoCollection(videoId, userId);
        return JsonRes.builder().success();
    }

    @Override
    public JsonRes getVideoCollection(Long videoId) {
        Long userId = null;
        try {
            userId = userSupport.getCurrentUserId(request);
        } catch (Exception ignored) {}
        LikeCoinOperatedCollectedInfo videoCollectionServiceVideoCollectionInfo
                = videoCollectionService.getVideoCollection(videoId, userId);
        return JsonRes.builder().success().data(videoCollectionServiceVideoCollectionInfo);
    }

    @UserAuthoritiesAccess(
            accessRole = {ConstantUtil.ROLE_LV0
                    ,ConstantUtil.ROLE_LV1
                    ,ConstantUtil.ROLE_LV2
                    ,ConstantUtil.ROLE_LV3
                    ,ConstantUtil.ROLE_LV4
                    ,ConstantUtil.ROLE_LV5
                    ,ConstantUtil.ROLE_LV6
            })
    @Override
    public JsonRes videoCoinOperated(Integer coinOperated, Long videoId) throws Exception {
        Long userId = userSupport.getCurrentUserId(request);
        String token = userSupport.getToken(request);
        videoCoinService.addVideoCoin(userId, videoId, coinOperated, token);
        return JsonRes.builder().success();
    }

    @Override
    public JsonRes getVideoCoins(Long videoId) {
        Long userId = null;
        try {
            userId = userSupport.getCurrentUserId(request);
        } catch (Exception e) {}
        LikeCoinOperatedCollectedInfo likeCoinOperatedCollectedInfo
                = videoCoinService.getVideoCoin(videoId, userId);
        return JsonRes.builder().success().data(likeCoinOperatedCollectedInfo);
    }

    @Override
    public JsonRes getVideoDetails(Long videoId) throws Exception {
        Map<String, Object> videoDetails = videoService.getVideoDetails(videoId);
        return JsonRes.builder().success().data(videoDetails);
    }

    @Override
    public JsonRes addVideoViewCount(VideoView videoView) throws ConditionException {
        //判断是否是游客，是游客就将userid设置到videoview
        Long userId;
        try {
            userId = userSupport.getCurrentUserId(request);
            videoView.setUserid(userId);
        } catch (Exception ignored) {}
        videoViewService.addVideoViewCount(videoView, request);
        return JsonRes.builder().success();
    }

    @Override
    public JsonRes getVideoViewCount(Long videoId) {
        //通过videoid统计videoview的次数
        Integer count = videoViewService.getVideoViewCount(videoId);
        return JsonRes.builder().success().data(count);
    }

    @Override
    public JsonRes recommend() throws Exception {
        Long userId = userSupport.getCurrentUserId(request);
        List<Video> recommendList = videoRecommendService.recommend(userId);
        return JsonRes.builder().success().data(recommendList);
    }

    @SentinelResource(
            entryType = EntryType.IN
            , blockHandler = "defaultExHandler"
            , blockHandlerClass = GlobalSystemDefendHandler.class
    )
    @Override
    public JsonRes getHomePageVideo(Long lastId, Integer pageSize) throws Exception {
        Long userId = null;
        try {
            userId = userSupport.getCurrentUserId(request);
        } catch (Exception ignored) {}
        List<Video> videos = videoService.getHomePageVideo(userId, lastId, pageSize);
        PageInfo pageInfo = PageInfo.builder().pageList(videos).size(videos.size()).build();
        return JsonRes.builder().success().data(pageInfo);
    }

    @Override
    public void removeVideo(Long videoId) throws ConditionException {
        videoService.removeVideo(videoId);
    }
}